home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / dev / e / jrhrkrm2.lzh / RKRM_PartTwo / Console / Console.e < prev   
Text File  |  1995-09-20  |  8KB  |  231 lines

  1. -> Console.e
  2. ->
  3. -> Example of opening a window and using the console device to send text and
  4. -> control sequences to it.  The example can be easily modified to do
  5. -> additional control sequences.
  6.  
  7. ->>> Header (globals)
  8. OPT PREPROCESS
  9.  
  10. MODULE 'devices/console',
  11.        'exec/io',
  12.        'exec/ports',
  13.        'intuition/intuition',
  14.        'intuition/screens',
  15.        'amigalib/io',
  16.        'amigalib/ports'
  17.  
  18. ENUM ERR_NONE, ERR_DEV, ERR_IO, ERR_PORT
  19.  
  20. RAISE ERR_DEV IF OpenDevice()<>0
  21.  
  22. -> Note - using two character <CSI> ESC[.  Hex 9B could be used instead
  23. #define RESETCON  '\ec'
  24. #define CURSOFF   '\e[0 p'
  25. #define CURSON    '\e[ p'
  26. #define DELCHAR   '\e[P'
  27.  
  28. -> SGR (set graphic rendition)
  29. #define COLOR02   '\e[32m'
  30. #define COLOR03   '\e[33m'
  31. #define ITALICS   '\e[3m'
  32. #define BOLD      '\e[1m'
  33. #define UNDERLINE '\e[4m'
  34. #define NORMAL    '\e[0m'
  35.  
  36. DEF win=NIL:PTR TO window, writeReq=NIL:PTR TO iostd, writePort=NIL:PTR TO mp,
  37.     readReq=NIL:PTR TO iostd, readPort=NIL:PTR TO mp, openedConsole=FALSE
  38. ->>>
  39.           
  40. ->>> PROC main()
  41. PROC main() HANDLE
  42.   DEF winmsg:PTR TO intuimessage, signals, conreadsig, windowsig, lch,
  43.       inControl=0, going=TRUE, ch, ibuf, obuf[200]:STRING, error, class
  44.  
  45.   -> Create reply port and io block for writing to console
  46.   IF NIL=(writePort:=createPort('RKM.console.write', 0)) THEN Raise(ERR_PORT)
  47.   IF NIL=(writeReq:=createExtIO(writePort, SIZEOF iostd)) THEN Raise(ERR_IO)
  48.  
  49.   -> Create reply port and io block for reading from console
  50.   IF NIL=(readPort:=createPort('RKM.console.read', 0)) THEN Raise(ERR_PORT)
  51.   IF NIL=(readReq:=createExtIO(readPort, SIZEOF iostd)) THEN Raise(ERR_IO)
  52.  
  53.   -> Open a window
  54.   win:=OpenWindow([10, 10, 620, 180, -1, -1, IDCMP_CLOSEWINDOW,
  55.                    WFLG_DEPTHGADGET OR WFLG_SIZEGADGET OR WFLG_DRAGBAR OR
  56.                      WFLG_CLOSEGADGET OR WFLG_SMART_REFRESH OR WFLG_ACTIVATE,
  57.                    NIL, NIL, 'Console Test', NIL, NIL,
  58.                    100, 45, 640, 200, WBENCHSCREEN]:nw)
  59.  
  60.   -> Now, attach a console to the window
  61.   openConsole(writeReq, readReq, win)
  62.   openedConsole:=TRUE
  63.  
  64.   -> Demonstrate some console escape sequences
  65.   conPuts(writeReq, 'Here''s some normal text\n')
  66.   StringF(obuf, '\s\sHere''s some text in color 3 and italics\n',
  67.                 COLOR03, ITALICS)
  68.   conPuts(writeReq, obuf)
  69.   conPuts(writeReq, NORMAL)
  70.   Delay(50)  -> Delay for dramatic effect
  71.  
  72.   conPuts(writeReq, 'We will now delete this asterisk =*=')
  73.   Delay(50)
  74.   conPuts(writeReq, {bspace})  -> Backspace twice
  75.   Delay(50)
  76.   conPuts(writeReq, DELCHAR)  -> Delete the character
  77.   Delay(50)
  78.  
  79.   queueRead(readReq, {ibuf})  -> Send the first console read request
  80.  
  81.   conPuts(writeReq, '\n\nNow reading console\n')
  82.   conPuts(writeReq, 'Type some keys.  Close window when done.\n\n')
  83.  
  84.   conreadsig:=Shl(1, readPort.sigbit)
  85.   windowsig:=Shl(1, win.userport.sigbit)
  86.   WHILE going
  87.     -> A character, or an IDCMP msg, or both could wake us up
  88.     signals:=Wait(conreadsig OR windowsig)
  89.  
  90.     -> If a console signal was received, get the character
  91.     IF signals AND conreadsig
  92.       IF -1<>(lch:=conMayGetChar(readPort, {ibuf}))
  93.         ch:=lch
  94.         -> Show hex and ascii (if printable) for char we got.  If you want to
  95.         -> parse received control sequences, such as function or Help keys,
  96.         -> you would buffer control sequences as you receive them, starting to
  97.         -> buffer whenever you receive $9B (or $1B[ for user-typed sequences)
  98.         -> and ending when you receive a valid terminating character for the
  99.         -> type of control sequence you are receiving.  For CSI sequences,
  100.         -> valid terminating characters are generally $40 through $7E.  In our
  101.         -> example, InControl has the following values: 0 = no, 1 = have $1B,
  102.         -> 2 = have $9B OR $1B and [, 3 = now inside control sequence,
  103.         -> -1 = normal end esc, -2 = non-CSI(no [) $1B end esc
  104.         -> NOTE - a more complex parser is required to recognize other types
  105.         -> of control sequences.
  106.  
  107.         -> $1B ESC not followed by "[", is not CSI seq
  108.         IF inControl=1 THEN (inControl:=IF ch="[" THEN 2 ELSE -2)
  109.         IF (ch=$9B) OR (ch=$1B)  -> Control seq starting
  110.           inControl:=IF ch=$1B THEN 1 ELSE 2
  111.           conPuts(writeReq, '=== Control Seq ===\n')
  112.         ENDIF
  113.         -> We'll show the value of this char we received
  114.         IF ((ch>=$1F) AND (ch<=$7E)) OR (ch>=$A0)
  115.           StringF(obuf, 'Received: hex $\z\h[2] = \c\n', ch, ch)
  116.         ELSE
  117.           StringF(obuf, 'Received: hex $\z\h[2]\n', ch)
  118.         ENDIF
  119.         conPuts(writeReq, obuf)
  120.       ENDIF
  121.     ENDIF
  122.  
  123.     -> If IDCMP messages received, handle them
  124.     IF signals AND windowsig
  125.       -> We have to ReplyMsg these when done with them
  126.       WHILE winmsg:=GetMsg(win.userport)
  127.         class:=winmsg.class
  128.         SELECT class
  129.         CASE IDCMP_CLOSEWINDOW
  130.           going:=FALSE
  131.         ENDSELECT
  132.         ReplyMsg(winmsg)
  133.       ENDWHILE
  134.     ENDIF
  135.   ENDWHILE
  136.  
  137.   -> We always have an outstanding queued read request so we must abort it if
  138.   -> it hasn't completed, and we must remove it.
  139.   IF CheckIO(readReq)=FALSE THEN AbortIO(readReq)
  140.   WaitIO(readReq)  -> Clear it from our replyport
  141.  
  142. EXCEPT DO
  143.   IF openedConsole THEN closeConsole(writeReq)
  144.   IF win THEN CloseWindow(win)
  145.   IF readReq THEN deleteExtIO(readReq)
  146.   IF readPort THEN deletePort(readPort)
  147.   IF writeReq THEN deleteExtIO(writeReq)
  148.   IF writePort THEN deletePort(writePort)
  149.   SELECT exception
  150.   CASE ERR_DEV;   WriteF('Error: could not open console device\n')
  151.   CASE ERR_IO;    WriteF('Error: could not create I/O\n')
  152.   CASE ERR_PORT;  WriteF('Error: could not create port\n')
  153.   ENDSELECT
  154. ENDPROC
  155.  
  156. -> E-Note: simple way to get a string with two backspaces
  157. bspace:  CHAR 8, 8, 0
  158. ->>>
  159.  
  160. ->>> PROC openConsole(writereq:PTR TO iostd, readReq:PTR TO iostd, window)
  161. -> Attach console device to an open Intuition window.
  162. -> E-Note: This function will raise an exception if the console device is not
  163. -> opened correctly.
  164. PROC openConsole(writereq:PTR TO iostd, readreq:PTR TO iostd, window)
  165.   DEF error
  166.   writereq.data:=window
  167.   writereq.length:=SIZEOF window
  168.   error:=OpenDevice('console.device', 0, writereq, 0)
  169.   readreq.device:=writereq.device  -> Clone required parts
  170.   readreq.unit:=writereq.unit
  171. ENDPROC error
  172. ->>>
  173.  
  174. ->>> PROC closeConsole(writereq)
  175. PROC closeConsole(writereq) IS CloseDevice(writereq)
  176. ->>>
  177.  
  178. ->>> PROC conPutChar(writereq:PTR TO iostd, char)
  179. -> Output a single character to a specified console.
  180. PROC conPutChar(writereq:PTR TO iostd, char)
  181.   writereq.command:=CMD_WRITE
  182.   -> E-Note: use typed list to get address of the CHAR in the LONG 'char'
  183.   writereq.data:=[char]:CHAR
  184.   writereq.length:=1
  185.   DoIO(writereq)
  186.   -> Command works because DoIO blocks until command is done (otherwise
  187.   -> pointer to string could become invalid in the meantime).
  188. ENDPROC
  189. ->>>
  190.  
  191. ->>> PROC conWrite(writereq:PTR TO iostd, string, length)
  192. -> Output a stream of known length to a console.
  193. PROC conWrite(writereq:PTR TO iostd, string, length)
  194.   writereq.command:=CMD_WRITE
  195.   writereq.data:=string
  196.   writereq.length:=length
  197.   DoIO(writereq)
  198. ENDPROC
  199. ->>>
  200.  
  201. ->>> PROC conPuts(writereq:PTR TO iostd, string)
  202. -> Output a NIL-terminated string of characters to a console.
  203. PROC conPuts(writereq:PTR TO iostd, string)
  204.   writereq.command:=CMD_WRITE
  205.   writereq.data:=string
  206.   writereq.length:=-1  -> This means print until terminating NIL
  207.   DoIO(writereq)
  208. ENDPROC
  209. ->>>
  210.  
  211. ->>> PROC queueRead(readreq:PTR TO iostd, whereto)
  212. -> Queue up a read request to console, passing it pointer to a buffer into
  213. -> which it can read the character
  214. PROC queueRead(readreq:PTR TO iostd, whereto)
  215.   readreq.command:=CMD_READ
  216.   readreq.data:=whereto
  217.   readreq.length:=1
  218.   SendIO(readreq)
  219. ENDPROC
  220. ->>>
  221.  
  222. ->>> PROC conMayGetChar(msgport, whereto)
  223. -> Check if a character has been received.  If none, return -1
  224. PROC conMayGetChar(msgport, whereto)
  225.   DEF temp, readreq:PTR TO iostd
  226.   IF NIL=(readreq:=GetMsg(msgport)) THEN RETURN -1
  227.   temp:=whereto[]  -> Get the character...
  228.   queueRead(readreq, whereto)  -> ...then re-use the request block
  229. ENDPROC temp
  230. ->>>
  231.